/**
 * 项目名：	Rumba Plan
 * 
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2006，所有权利保留。
 * 
 * 文件名：	ViewRole.java
 * 模块说明：	
 * 修改历史：
 * 2006-8-30 - lxm - 创建。
 */
package com.hd123.rumba.action.user;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import net.sf.hibernate.HibernateException;

import com.hd123.rumba.action.log.ViewEntityLogs;
import com.hd123.rumba.domain.CDomain;
import com.hd123.rumba.domain.biz.IBDomainMgr;
import com.hd123.rumba.domain.biz.SDomain;
import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.exception.StringTooLongException;
import com.hd123.rumba.log.ActionLogger;
import com.hd123.rumba.request.ActionAbstractImpl;
import com.hd123.rumba.request.ActionConstants;
import com.hd123.rumba.request.JspLib;
import com.hd123.rumba.runtime.FormatSettings;
import com.hd123.rumba.runtime.NamingMgr;
import com.hd123.rumba.runtime.OperateContext;
import com.hd123.rumba.sql.biz.BResultPage;
import com.hd123.rumba.sql.biz.BSQLSubquery;
import com.hd123.rumba.user.CPermission;
import com.hd123.rumba.user.CRole;
import com.hd123.rumba.user.CUser;
import com.hd123.rumba.user.IPermissionMgr;
import com.hd123.rumba.user.biz.BBasePermAssign;
import com.hd123.rumba.user.biz.BPermGroupAssign;
import com.hd123.rumba.user.biz.BPermissionCommand;
import com.hd123.rumba.user.biz.BRole;
import com.hd123.rumba.user.biz.BUser;
import com.hd123.rumba.user.biz.IBPermAgent;
import com.hd123.rumba.user.biz.IBRoleMgr;
import com.hd123.rumba.user.biz.IBUserMgr;
import com.hd123.rumba.user.biz.SRole;
import com.hd123.rumba.user.biz.SUser;
import com.hd123.rumba.user.biz.share.BRoleMemberAssign;
import com.hd123.rumba.user.biz.share.BRoleMemberCommand;
import com.hd123.rumba.user.biz.share.BRoleShareAssign;
import com.hd123.rumba.user.biz.share.BRoleShareCommand;
import com.hd123.rumba.user.biz.share.IBRoleMemberAgent;
import com.hd123.rumba.user.biz.share.IBRoleShareAgent;
import com.hd123.rumba.util.ClassifiedHashtable;

/**
 * 角色 | Action | 基类
 * 
 * @author lxm
 * 
 */
public abstract class BaseViewRole extends ActionAbstractImpl {

  /* Templates */
  protected static final String TEMPLATE_LIST = "user/RolesList.jsp";
  protected static final String TEMPLATE_FILTER = "user/RolesFilter.jsp";
  protected static final String TEMPLATE_CREATE = "user/RoleCreate.jsp";
  protected static final String TEMPLATE_VIEW = "user/RoleView.jsp";
  protected static final String TEMPLATE_EDIT = "user/RoleEdit.jsp";
  protected static final String TEMPLATE_USERSEDIT = "user/RoleUsersEdit.jsp";
  protected static final String TEMPLATE_PERMISSIONSEDIT = "user/RolePermissionsEdit.jsp";
  protected static final String TEMPLATE_BROWSERDEF = "user/RoleBrowserDef.jsp";
  protected static final String TEMPLATE_PUBLIC_VIEW = "user/role/PublicRoleView.jsp";
  protected static final String TEMPLATE_PUBLIC_EDIT = "user/role/PublicRoleEdit.jsp";
  protected static final String TEMPLATE_PUBLIC_SHAREEDIT = "user/role/PublicRoleShareEdit.jsp";
  protected static final String TEMPLATE_PUBLIC_USERSEDIT = "user/role/PublicRoleUsersEdit.jsp";
  protected static final String TEMPLATE_PUBLIC_PERMISSIONSEDIT = "user/role/PublicRolePermissionsEdit.jsp";

  public String list() throws Exception {
    SDomain domain = getFormDomain();
    String isRecycleStr = (String) dd.getFormValue("isRecycle");
    if (isRecycleStr == null)
      isRecycleStr = "FALSE";
    Boolean isRecycle = "TRUE".equalsIgnoreCase(isRecycleStr) ? Boolean.TRUE : Boolean.FALSE;
    String permId = this.getPermission(ViewRole.FUNCTION_VIEW, domain.getUuid(), isRecycle);
    if (permId != null && !this.getCurrentUser().hasPermission(permId))
      return ActionConstants.NOACCESS;

    RoleFilter filter = getFormFilter();

    return this.showListSafely(filter, domain, isRecycle);
  }

  public String filter() throws Exception {
    SDomain domain = getFormDomain();
    RoleFilter filter = getFormFilter();
    String isRecycleStr = (String) dd.getFormValue("isRecycle");
    if (isRecycleStr == null)
      isRecycleStr = "FALSE";
    Boolean isRecycle = "TRUE".equalsIgnoreCase(isRecycleStr) ? Boolean.TRUE : Boolean.FALSE;
    String permId = this.getPermission(ViewRole.FUNCTION_VIEW, domain.getUuid(), isRecycle);
    if (permId != null && !this.getCurrentUser().hasPermission(permId))
      return ActionConstants.NOACCESS;

    dd.put("filter", filter);
    dd.put("domain", domain);
    dd.put("isRecycle", isRecycle);
    dd.setWorkingTemplate(TEMPLATE_FILTER);
    return ActionConstants.APPLICATIONFRAME;
  }

  public String create() throws Exception {
    SDomain domain = getFormDomain();
    BRole role = getBRoleMgr().createRole(domain.getUuid());

    return showDetailSafely(role, domain, JspLib.VALUE_FORMSTATE_CREATE, true);
  }

  public String view() throws Exception {
    SDomain domain = getFormDomain();
    String uuid = (String) dd.getFormValue("role_uuid");
    if (uuid == null)
      throw new Exception("缺少必须的参数role_uuid。");

    BRole role = getBRoleMgr().loadRole(uuid);

    String tabView = (String) dd.getFormValue("tabView");
    if (tabView == null) {
      if (CRole.VALUE_ROLETYPE_PUBLIC.equals(role.getRoleType()))
        tabView = "tvShare";
      else
        tabView = "tvUsers";
    }
    dd.put("tabView", tabView);
    return showDetailSafely(role, domain, JspLib.VALUE_FORMSTATE_VIEW, true);
  }

  public String edit() throws Exception {
    SDomain domain = getFormDomain();
    String uuid = (String) dd.getFormValue("role_uuid");
    if (uuid == null)
      throw new Exception("缺少必须的参数role_uuid。");
    String ocaStr = (String) dd.getFormValue("role_oca");
    if (ocaStr == null)
      throw new Exception("缺少必须的参数role_oca。");
    long oca = Long.valueOf(ocaStr).longValue();

    BRole role = getBRoleMgr().loadRole(uuid);

    this.checkOca(role, oca, CRole.CAPTION_CLASS);

    return showDetailSafely(role, domain, JspLib.VALUE_FORMSTATE_EDIT, true);
  }

  public String save() throws Exception {
    SDomain domain = getFormDomain();
    String formState = (String) dd.getFormValue("formState");
    String uuid = (String) dd.getFormValue("role_uuid");
    if ("".equals(uuid))
      uuid = null;
    BRole role = null;
    boolean isNew;

    try {
      if (uuid == null) {
        String domainUuid = (String) dd.getFormValue("role_domain_uuid");
        role = getBRoleMgr().createRole(domainUuid);
        isNew = true;
      } else {
        role = getBRoleMgr().loadRole(uuid);
        isNew = false;
      }
      readFormRole(role);
      if (isNew)
        logger.info(ActionLogger.EVENT_SAVENEW, role.getNameCode());
      else
        logger.info(ActionLogger.EVENT_SAVE, CRole.CAPTION_UUID + "=\"" + role.getUuid() + "\"。");
      if (!dd.isFormValid())
        return showDetailSafely(role, domain, formState, false);
      ClassifiedHashtable h = getBRoleMgr().saveRoleT(role, new OperateContext(getCurrentUser()));
      if (h != null && h.size() > 0) {
        dd.addInvalidFormValues("role_", h);
        // oca错误需要特殊处理：取消所做的修改。
        if (h.getMessage("oca") != null && uuid != null) { // 断言条件uuid
          // !=
          // null，即非新增状态。
          dd.putFormValue("role_uuid", role.getUuid());
          return view();
        } else
          return showDetailSafely(role, domain, formState, false);
      }
    } catch (Exception e) {
      dd.addErrorText(e.getMessage());
      return showDetailSafely(role, domain, formState, false);
    }

    dd.putFormValue("role_uuid", role.getUuid());
    dd.addHint(CRole.CAPTION_CLASS + "已保存。");
    return view();
  }

  public String delete() throws Exception {
    SDomain domain = getFormDomain();
    String uuid = (String) dd.getFormValue("role_uuid");
    if (uuid == null)
      throw new Exception("缺少必须的参数role_uuid。");
    String ocaStr = (String) dd.getFormValue("role_oca");
    if (ocaStr == null)
      throw new Exception("缺少必须的参数role_oca。");
    long oca = Long.valueOf(ocaStr).longValue();

    try {
      delete2(uuid, oca);
    } catch (Exception e) {
      dd.addErrorText(e.getMessage());
    }
    BRole role = (BRole) getBRoleMgr().getRole(uuid, BRole.class);
    dd.addHint(CRole.CAPTION_CLASS + "已被删除。");
    return showDetailSafely(role, domain, JspLib.VALUE_FORMSTATE_VIEW, false);
  }

  public String undelete() throws Exception {
    SDomain domain = getFormDomain();
    String uuid = (String) dd.getFormValue("role_uuid");
    if (uuid == null)
      throw new Exception("缺少必须的参数role_uuid。");
    String ocaStr = (String) dd.getFormValue("role_oca");
    if (ocaStr == null)
      throw new Exception("缺少必须的参数role_oca。");
    long oca = Long.valueOf(ocaStr).longValue();

    try {
      undelete2(uuid, oca);
    } catch (Exception e) {
      dd.addErrorText(e.getMessage());
    }
    BRole role = (BRole) getBRoleMgr().getRole(uuid, BRole.class);
    dd.addHint(CRole.CAPTION_CLASS + "已被恢复删除。");
    return showDetailSafely(role, domain, JspLib.VALUE_FORMSTATE_VIEW, false);
  }

  public String editRolePermissions() throws Exception {
    logger.info(ActionLogger.EVENT_EDIT, "编辑" + CRole.CAPTION_CLASS + "拥有的"
        + CPermission.CAPTION_CLASS + "。");

    String uuid = (String) dd.getFormValue("role_uuid");
    if (uuid == null)
      throw new Exception("缺少必须的参数role_uuid。");
    String ocaStr = (String) dd.getFormValue("role_oca");
    if (ocaStr == null)
      throw new Exception("缺少必须的参数role_oca。");
    long oca = Long.valueOf(ocaStr).longValue();

    BRole role = getBRoleMgr().loadRole(uuid);

    this.checkOca(role, oca, CRole.CAPTION_CLASS);

    return showRolePermissionsEditSafely(role);
  }

  public String saveRolePermissions() throws Exception {
    SDomain domain = getFormDomain();
    String uuid = (String) dd.getFormValue("role_uuid");
    if (uuid == null)
      throw new Exception("缺少必须的参数role_uuid。");
    String ocaStr = (String) dd.getFormValue("role_oca");
    if (ocaStr == null)
      throw new Exception("缺少必须的参数role_oca。");
    long oca = Long.valueOf(ocaStr).longValue();

    List<BPermissionCommand> cmdList = getFormPermissionCommands();
    if (cmdList.size() > 0) {
      logger.info(ActionLogger.EVENT_SAVE, "修改拥有的" + CPermission.CAPTION_CLASS + "。");
      IBPermAgent agent = getBRoleMgr().createRolePermAgent(uuid);
      try {
        agent.executeCommandsT(cmdList, new OperateContext(getCurrentUser()), oca);
      } catch (Exception e) {
        e.printStackTrace();
        dd.addErrorText(e.getMessage());
        return showRolePermissionsEditSafely(uuid);
      }
    }

    BRole role = getBRoleMgr().loadRole(uuid);
    dd.addHint(CRole.CAPTION_CLASS + "拥有的" + CPermission.CAPTION_CLASS + "已保存。");
    dd.put("tabView", "tvPermissions");
    return showDetailSafely(role, domain, JspLib.VALUE_FORMSTATE_VIEW, false);
  }

  public String browse() throws Exception {
    dd.put("entityCaption", CRole.CAPTION_CLASS);
    dd.put("entityIcon", "rumba/images/user/role_small.gif");
    dd.setWorkingTemplate(TEMPLATE_BROWSERDEF);
    return ActionConstants.BROWSERFRAME;
  }

  /**
   * 用于汇总页面角色列表的查询。
   * 
   * @param bsq
   * @param pageSize
   * @param page
   * @return
   * @throws Exception
   */
  public BResultPage queryList(BSQLSubquery bsq, int pageSize, int page) throws Exception {
    try {
      addForceFilter(bsq);
      return this.query(bsq, pageSize, page);
    } catch (Exception e) {
      this.reportError("", e);
      throw e;
    }
  }

  /**
   * 删除指定的角色。
   * 
   * @param uuid
   *          被删除角色的uuid。
   * @param oca
   * @throws Exception
   */
  public void delete2(String uuid, long oca) throws Exception {
    try {
      logger.info(ActionLogger.EVENT_DELETE, "uuid=" + uuid);
      getBRoleMgr().deleteRoleT(uuid, new OperateContext(getCurrentUser()), oca);
    } catch (Exception e) {
      this.reportError("", e);
      throw e;
    }
  }

  /**
   * 恢复删除指定的角色。
   * 
   * @param uuid
   * @param oca
   * @throws Exception
   */
  public void undelete2(String uuid, long oca) throws Exception {
    try {
      logger.info(ActionLogger.EVENT_UNDELETE, "uuid=" + uuid);
      getBRoleMgr().undeleteRoleT(uuid, new OperateContext(getCurrentUser()), oca);
    } catch (Exception e) {
      this.reportError("", e);
      throw e;
    }
  }

  public SRole getRoleByCode(String domainUuid, String code) throws Exception {
    try {
      return (SRole) getBRoleMgr().getRoleByCode(domainUuid, code, SRole.class);
    } catch (Exception e) {
      this.reportError("", e);
      throw e;
    }
  }

  public BPermGroupAssign getGlobalPermGroups(Boolean projection, String roleUuid) throws Exception {
    try {
      IBPermAgent agent = getBRoleMgr().createRolePermAgent(roleUuid);
      return agent.getGlobalPermGroup();
    } catch (Exception e) {
      this.reportError("", e);
      throw e;
    }
  }

  public BRoleShareAssign getRoleShareAssign(String roleUuid, String domainUuid) throws Exception {
    try {
      IBRoleShareAgent agent = getBRoleMgr().createRoleShareAgent(roleUuid);
      return agent.getShareAssign(domainUuid);
    } catch (Exception e) {
      this.reportError("", e);
      throw e;
    }
  }

  public List<BRoleShareAssign> getRoleLowerShareAssigns(String roleUuid, String domainUuid)
      throws Exception {
    try {
      IBRoleShareAgent agent = getBRoleMgr().createRoleShareAgent(roleUuid);
      return agent.getLowerShareAssigns(domainUuid);
    } catch (Exception e) {
      this.reportError("", e);
      throw e;
    }
  }

  public BRoleMemberAssign getRoleMemberAssign(String roleUuid, String domainUuid) throws Exception {
    try {
      IBRoleMemberAgent agent = getBRoleMgr().createRoleMemberAgent(roleUuid);
      return agent.getMemberAssign(domainUuid);
    } catch (Exception e) {
      this.reportError("", e);
      throw e;
    }
  }

  public List<BRoleMemberAssign> getRoleLowerMemberAssigns(String roleUuid, String domainUuid)
      throws Exception {
    try {
      IBRoleMemberAgent agent = getBRoleMgr().createRoleMemberAgent(roleUuid);
      return agent.getLowerMemberAssigns(domainUuid);
    } catch (Exception e) {
      this.reportError("", e);
      throw e;
    }
  }

  public List<BPermGroupAssign> getCFVPermGroups(Boolean projection, String roleUuid)
      throws Exception {
    try {
      IBPermAgent agent = getBRoleMgr().createRolePermAgent(roleUuid);
      return agent.getCFVPermGroups();
    } catch (Exception e) {
      this.reportError("", e);
      throw e;
    }
  }

  public List<BPermGroupAssign> getProviderPermGroups(Boolean projection, String roleUuid,
      String cfvUuid) throws Exception {
    try {
      IBPermAgent agent = getBRoleMgr().createRolePermAgent(roleUuid);
      return agent.getProviderPermGroups(cfvUuid);
    } catch (Exception e) {
      this.reportError("", e);
      throw e;
    }
  }

  public List<BBasePermAssign> getPermissions(Boolean projection, String roleUuid, String cfvUuid,
      String providerClassName) throws Exception {
    try {
      IBPermAgent agent = getBRoleMgr().createRolePermAgent(roleUuid);
      return agent.getPermissions(cfvUuid, providerClassName);
    } catch (Exception e) {
      this.reportError("", e);
      throw e;
    }
  }

  /**
   * 根据功能等信息取得权限ID。
   * 
   * @param functionName
   *          功能名，取值为类似“FUNCTION_*”的常量。
   * @param domainUuid
   *          指定角色所在域的uuid。
   * @param isRecycle
   *          是否是回收站。
   * @return 返回权限ID，若没有权限对应则返回null。
   * @throws BusinessException
   * @throws HibernateException
   */
  public abstract String getPermission(String functionName, String domainUuid, Boolean isRecycle)
      throws BusinessException, HibernateException;

  /**
   * 添加对用户的强制筛选条件。
   * 
   * @param bsq
   */
  protected abstract void addForceFilter(BSQLSubquery bsq) throws BusinessException,
      HibernateException;

  private IBRoleMgr roleMgr = null;

  protected IBRoleMgr getBRoleMgr() throws BusinessException {
    if (roleMgr == null)
      roleMgr = (IBRoleMgr) NamingMgr.getInstance().lookupMgr(IBRoleMgr.class);
    return roleMgr;
  }

  private SDomain getFormDomain() throws Exception {
    String domainUuid = (String) dd.getFormValue("domain_uuid");
    if (domainUuid == null)
      domainUuid = dd.getCurrentDomain().getUuid();
    IBDomainMgr dmMgr = (IBDomainMgr) NamingMgr.getInstance().lookupMgr(IBDomainMgr.class);
    SDomain dm = dmMgr.getDomain(domainUuid);
    if (dm == null)
      throw new BusinessException("找不到指定的" + CDomain.CAPTION_CLASS + "(" + domainUuid + ")。");
    return dm;
  }

  private RoleFilter getFormFilter() throws Exception {
    RoleFilter filter = new RoleFilter();
    filter.setCodeLike((String) dd.getFormValue("filter_codeLike"));
    filter.setNameLike((String) dd.getFormValue("filter_nameLike"));
    return filter;
  }

  /**
   * 检查用户权限，尝试显示列表页面。
   * <p>
   * 
   * 如果要求显示的是正常的列表页面，则先检查是否具有正常查看权，若没有，则显示NOACCESS页面；<br>
   * 如果要求显示的是回收站的列表页面，则先检查是否有回收站查看权，若没有，则再尝试显示正常的列表页面，若还没有，则显示NOACCESS页面。
   * 
   * @param filter
   * @param domain
   * @param isRecycle
   * @return
   * @throws Exception
   */
  private String showListSafely(RoleFilter filter, SDomain domain, Boolean isRecycle)
      throws Exception {
    String permId = this.getPermission(ViewRole.FUNCTION_VIEW, domain.getUuid(), isRecycle);
    if (!this.getCurrentUser().hasPerm(permId)) {
      if (isRecycle.booleanValue())
        return showListSafely(filter, domain, Boolean.valueOf(!isRecycle.booleanValue()));
      else
        return showNoAccess();
    }
    return showList(filter, domain, isRecycle);
  }

  private String showList(RoleFilter filter, SDomain domain, Boolean isRecycle) throws Exception {
    dd.put("filter", filter);
    dd.put("domain", domain);
    dd.put("isRecycle", isRecycle);
    this.putFormPermissions(domain, isRecycle);
    if (!isRecycle.booleanValue())
      logger.info(ActionLogger.EVENT_LIST, null);
    else
      logger.info(ActionLogger.EVENT_RECYCLE_LIST, null);
    dd.setWorkingTemplate(TEMPLATE_LIST);
    return ActionConstants.APPLICATIONFRAME;
  }

  /**
   * 尝试显示明细页面。
   * <p>
   * 
   * 若指定显示的是编辑页面，将尝试检查是否具有编辑权限，若没有则尝试显示查看页面。<br>
   * 当检查权限的时候，若当前用户缺少访问指定页面的权限，将尝试显示列表页面（通过调用{@link #showList()}）。
   * 
   * @param role
   * @param domain
   * @param formState
   * @param directly
   * @return
   * @throws Exception
   */
  private String showDetailSafely(BRole role, SDomain domain, String formState, boolean directly)
      throws Exception {
    if (role == null)
      role = getBRoleMgr().createRole((String) dd.getFormValue("domain_uuid"));
    Boolean isRecycle = CRole.VALUE_STATE_DELETED.equals(role.getState()) ? Boolean.TRUE
        : Boolean.FALSE;
    String funcName = null;
    if (JspLib.VALUE_FORMSTATE_CREATE.equals(formState))
      funcName = ViewRole.FUNCTION_CREATE;
    else if (JspLib.VALUE_FORMSTATE_EDIT.equals(formState))
      funcName = ViewRole.FUNCTION_EDIT;
    else
      funcName = ViewRole.FUNCTION_VIEW;
    String permId = this.getPermission(funcName, role.getDomain().getUuid(), isRecycle);
    if (!this.getCurrentUser().hasPerm(permId)) {
      if (directly)
        dd.addErrorText("您缺少对指定" + CRole.CAPTION_CLASS + "进行" + funcName + "的权限。");
      if (JspLib.VALUE_FORMSTATE_EDIT.equals(formState))
        return showDetailSafely(role, domain, JspLib.VALUE_FORMSTATE_VIEW, false);
      else
        return this.showListSafely(this.getFormFilter(), role.getDomain(), isRecycle);
    }

    return showDetail(role, domain, formState);
  }

  private String showDetail(BRole role, SDomain domain, String formState) throws Exception {
    boolean isRecycle = CRole.VALUE_STATE_DELETED.equals(role.getState());
    dd.put("domain", domain);
    dd.put("role", role);

    IPermissionMgr permMgr = (IPermissionMgr) NamingMgr.getInstance().lookupMgr(
        IPermissionMgr.class);
    dd.put("am", permMgr.createFieldsAccessMode(getCurrentUser(), CRole.class));

    this.putFormPermissions(role.getDomain(), Boolean.valueOf(isRecycle));
    dd.putFormValue(JspLib.ID_FORMSTATE, formState);
    if (JspLib.VALUE_FORMSTATE_CREATE.equals(formState)) {
      logger.info(ActionLogger.EVENT_CREATE, null);
      dd.setWorkingTemplate(TEMPLATE_CREATE);
    } else if (JspLib.VALUE_FORMSTATE_VIEW.equals(formState)) {
      logger.info(ActionLogger.EVENT_VIEW, null);
      if (CRole.VALUE_ROLETYPE_PUBLIC.equals(role.getRoleType()))
        dd.setWorkingTemplate(TEMPLATE_PUBLIC_VIEW);
      else
        dd.setWorkingTemplate(TEMPLATE_VIEW);
      ViewEntityLogs.preloadJSP(dd, role.getUuid(), CRole.STATEMAP);
    } else {
      logger.info(ActionLogger.EVENT_EDIT, null);
      if (CRole.VALUE_ROLETYPE_PUBLIC.equals(role.getRoleType()))
        dd.setWorkingTemplate(TEMPLATE_PUBLIC_EDIT);
      else
        dd.setWorkingTemplate(TEMPLATE_EDIT);
    }
    return ActionConstants.APPLICATIONFRAME;
  }

  private void readFormRole(BRole role) throws Exception {
    boolean isRootAdmin = false;
    if (CDomain.VALUE_ID_ROOT.equals(this.getCurrentDomain().getCode())
        && CRole.VALUE_CODE_ROOT_ADMIN.equalsIgnoreCase(role.getCode()))
      isRootAdmin = true;

    String ocaStr = (String) dd.getFormValue("role_oca");
    role.setOca((new Long(ocaStr)).longValue());
    if (!isRootAdmin)
      role.setCode((String) dd.validateFormValue("role_code", null, true, role.getCode(),
          CRole.CAPTION_CODE));
    role.setName((String) dd.validateFormValue("role_name", null, true, role.getName(),
        CRole.CAPTION_NAME));
    role.setRemark((String) dd.validateFormValue("role_remark", null, false, role.getRemark(),
        CRole.CAPTION_REMARK));
    role.setRoleType((Integer) dd.validateFormValue("role_roleType", FormatSettings.VALID_INTEGER,
        true, role.getRoleType(), CRole.CAPTION_ROLETYPE));
  }

  private String showRolePermissionsEditSafely(String roleUuid) throws Exception {
    BRole role = getBRoleMgr().loadRole(roleUuid);
    return showRolePermissionsEditSafely(role);
  }

  private String showRolePermissionsEditSafely(BRole role) throws Exception {
    String permId = this.getPermission(ViewUser.FUNCTION_EDIT, role.getDomain().getUuid(),
        Boolean.valueOf(CUser.VALUE_STATE_DELETED.equals(role.getState())));
    if (!this.getCurrentUser().hasPerm(permId)) {
      dd.addErrorText("您缺少对指定" + CRole.CAPTION_CLASS + "进行" + ViewRole.FUNCTION_EDIT + "的权限。");
      return showDetailSafely(role, role.getDomain(), JspLib.VALUE_FORMSTATE_VIEW, false);
    }
    return showRolePermissionsEdit(role);
  }

  private String showRolePermissionsEdit(BRole role) throws Exception {
    dd.put("role", role);
    if (CRole.VALUE_ROLETYPE_PUBLIC.equals(role.getRoleType()))
      dd.setWorkingTemplate(TEMPLATE_PUBLIC_PERMISSIONSEDIT);
    else
      dd.setWorkingTemplate(TEMPLATE_PERMISSIONSEDIT);
    return ActionConstants.APPLICATIONFRAME;
  }

  private List<BPermissionCommand> getFormPermissionCommands() throws Exception {
    List<BPermissionCommand> cmdList = new ArrayList();
    Iterator keyIterator = dd.createFormPrefixedKeysIterator("ptree_commands_");
    List<String> keys = new ArrayList();
    while (keyIterator.hasNext())
      keys.add((String) keyIterator.next());
    Collections.sort(keys);
    for (int i = 0; i < keys.size(); i++) {
      String key = keys.get(i);
      String value = (String) dd.getFormValue("ptree_commands_" + key);
      String[] items = value.split(";");
      BPermissionCommand cmd = new BPermissionCommand();
      if (!"".equals(items[0]))
        cmd.setCartFunctionViewUuid(items[0]);
      if (!"".equals(items[1]))
        cmd.setProviderClassName(items[1]);
      if (!"".equals(items[2]))
        cmd.setFieldCaption(items[2]);
      if (!"".equals(items[3]))
        cmd.setPermissionCode(items[3]);
      if ("".equals(items[4]))
        continue;
      cmd.setCommand(new Integer(items[4]));
      cmdList.add(cmd);
    }
    return cmdList;
  }

  private void putFormPermissions(SDomain domain, Boolean isRecycle) throws BusinessException,
      HibernateException {
    String permId = null;
    permId = this.getPermission(ViewRole.FUNCTION_CREATE, domain.getUuid(), isRecycle);
    if (permId != null)
      dd.put("permissionCreate", permId);
    permId = this.getPermission(ViewRole.FUNCTION_DELETE, domain.getUuid(), isRecycle);
    if (permId != null)
      dd.put("permissionDelete", permId);
    permId = this.getPermission(ViewRole.FUNCTION_UNDELETE, domain.getUuid(), isRecycle);
    if (permId != null)
      dd.put("permissionUndelete", permId);
    permId = this.getPermission(ViewRole.FUNCTION_VIEW, domain.getUuid(), isRecycle);
    if (permId != null)
      dd.put("permissionView", permId);
    permId = this.getPermission(ViewRole.FUNCTION_EDIT, domain.getUuid(), isRecycle);
    if (permId != null)
      dd.put("permissionEdit", permId);
    permId = this.getPermission(ViewRole.FUNCTION_VIEW, domain.getUuid(), new Boolean(!isRecycle
        .booleanValue()));
    if (permId != null)
      dd.put("permissionAnotherView", permId);
    permId = this.getPermission(ViewRole.FUNCTION_SHARE, domain.getUuid(), isRecycle);
    if (permId != null)
      dd.put("permissionShare", permId);
  }

  public String editRoleUsers() throws Exception {
    logger.info(ActionLogger.EVENT_EDIT, "编辑" + CRole.CAPTION_CLASS + "包含的" + CUser.CAPTION_ROLES
        + "。");

    String uuid = (String) dd.getFormValue("role_uuid");
    if (uuid == null)
      throw new Exception("缺少必须的参数role_uuid。");
    String ocaStr = (String) dd.getFormValue("role_oca");
    if (ocaStr == null)
      throw new Exception("缺少必须的参数role_oca。");
    long oca = Long.valueOf(ocaStr).longValue();

    BRole role = getBRoleMgr().loadRole(uuid);

    this.checkOca(role, oca, CRole.CAPTION_CLASS);

    return showRoleUsersEditSafely(role);
  }

  private String showRoleUsersEditSafely(String roleUuid) throws Exception {
    BRole role = getBRoleMgr().loadRole(roleUuid);
    return showRoleUsersEditSafely(role);
  }

  private String showRoleUsersEditSafely(BRole role) throws Exception {
    String permId = this.getPermission(ViewUser.FUNCTION_EDIT, role.getDomain().getUuid(),
        Boolean.valueOf(CUser.VALUE_STATE_DELETED.equals(role.getState())));
    if (!this.getCurrentUser().hasPerm(permId)) {
      dd.addErrorText("您缺少对指定" + CRole.CAPTION_CLASS + "进行" + ViewRole.FUNCTION_EDIT + "的权限。");
      return showDetailSafely(role, role.getDomain(), JspLib.VALUE_FORMSTATE_VIEW, false);
    }
    return showRoleUsersEdit(role);
  }

  private String showRoleUsersEdit(BRole role) throws Exception {
    List<SUser> roleUsers = getBRoleMgr().loadRoleUsers(role.getUuid());
    IBUserMgr userMgr = (IBUserMgr) NamingMgr.getInstance().lookupMgr(IBUserMgr.class);
    List<BUser> allUsers = userMgr.getAllUsers(role.getDomain().getUuid());

    dd.put("role", role);
    dd.put("roleUsers", roleUsers);
    dd.put("allUsers", allUsers);
    if (CRole.VALUE_ROLETYPE_PUBLIC.equals(role.getRoleType()))
      dd.setWorkingTemplate(TEMPLATE_PUBLIC_USERSEDIT);
    else
      dd.setWorkingTemplate(TEMPLATE_USERSEDIT);
    return ActionConstants.APPLICATIONFRAME;
  }

  public String saveRoleUsers() throws Exception {
    SDomain domain = getFormDomain();
    String uuid = (String) dd.getFormValue("role_uuid");
    if (uuid == null)
      throw new Exception("缺少必须的参数role_uuid。");
    String ocaStr = (String) dd.getFormValue("role_oca");
    if (ocaStr == null)
      throw new Exception("缺少必须的参数role_oca。");
    long oca = Long.valueOf(ocaStr).longValue();

    BRole role = (BRole) getBRoleMgr().getRole(uuid, BRole.class);
    if (role == null)
      throw new Exception("找不到指定的角色(uuid=" + uuid + ")。");
    if (CRole.VALUE_ROLETYPE_PUBLIC.equals(role.getRoleType())) {
      List<BRoleMemberCommand> cmds = getFormRoleMemberCommands();
      if (cmds.size() > 0) {
        IBRoleMemberAgent agent = getBRoleMgr().createRoleMemberAgent(uuid);
        try {
          agent.executeCommandsT(cmds, new OperateContext(getCurrentUser()), oca);
        } catch (Exception e) {
          e.printStackTrace();
          dd.addErrorText(e.getMessage());
          return showRolePermissionsEditSafely(uuid);
        }
      }
    } else {
      IBUserMgr userMgr = (IBUserMgr) NamingMgr.getInstance().lookupMgr(IBUserMgr.class);
      List<SUser> list = new ArrayList<SUser>();
      Iterator userUuids = dd.createFormSelectedValuesIterator("role_user_uuids");
      while (userUuids.hasNext()) {
        String userUuid = (String) userUuids.next();
        SUser user = (SUser) userMgr.getUser(userUuid, SUser.class);
        list.add(user);
      }

      try {
        ClassifiedHashtable h = getBRoleMgr().saveRoleUsersT(uuid, list,
            new OperateContext(this.getCurrentUser()), oca);
        if (h != null && h.size() > 0) {
          dd.addInvalidFormValues("user_", h);
          return showRoleUsersEditSafely(uuid);
        }
      } catch (Exception e) {
        dd.addErrorText(e.getMessage());
        return showRoleUsersEditSafely(uuid);
      }
    }
    dd.put("tabView", "tvUsers");
    return view();
  }

  private List<BRoleMemberCommand> getFormRoleMemberCommands() {
    List<BRoleMemberCommand> cmds = new ArrayList<BRoleMemberCommand>();
    Iterator keyIterator = dd.createFormPrefixedKeysIterator("user_commands_");
    List<String> keys = new ArrayList<String>();
    while (keyIterator.hasNext())
      keys.add((String) keyIterator.next());
    Collections.sort(keys);
    for (int i = 0; i < keys.size(); i++) {
      String key = keys.get(i);
      String value = (String) dd.getFormValue("user_commands_" + key);
      String[] items = value.split(";");
      BRoleMemberCommand cmd = new BRoleMemberCommand();
      cmd.setUserUuid(items[0]);
      cmd.setCommand(new Integer(items[1]));
      cmds.add(cmd);
    }
    return cmds;
  }

  public String editRoleShare() throws Exception {
    logger.info(ActionLogger.EVENT_EDIT, "编辑" + CRole.CAPTION_CLASS + "共享的组织(域)。");

    SDomain domain = getFormDomain();
    String uuid = (String) dd.getFormValue("role_uuid");
    if (uuid == null)
      throw new Exception("缺少必须的参数role_uuid。");
    String ocaStr = (String) dd.getFormValue("role_oca");
    if (ocaStr == null)
      throw new Exception("缺少必须的参数role_oca。");
    long oca = Long.valueOf(ocaStr).longValue();

    BRole role = getBRoleMgr().loadRole(uuid);

    this.checkOca(role, oca, CRole.CAPTION_CLASS);

    return showRoleShareEditSafely(domain, role);
  }

  private String showRoleShareEditSafely(SDomain domain, BRole role) throws Exception {
    String permId = this.getPermission(ViewRole.FUNCTION_EDIT, role.getDomain().getUuid(),
        Boolean.valueOf(CRole.VALUE_STATE_DELETED.equals(role.getState())));
    if (!this.getCurrentUser().hasPerm(permId)) {
      dd.addErrorText("您缺少对指定" + CRole.CAPTION_CLASS + "进行" + ViewRole.FUNCTION_EDIT + "的权限。");
      return showDetailSafely(role, role.getDomain(), JspLib.VALUE_FORMSTATE_VIEW, false);
    }
    return showRoleShareEdit(domain, role);
  }

  private String showRoleShareEdit(SDomain domain, BRole role) throws Exception {
    List<SDomain> shareDomains = getBRoleMgr().loadRoleShareDomains(role.getUuid());
    IBDomainMgr bdomainMgr = (IBDomainMgr) NamingMgr.getInstance().lookupMgr(IBDomainMgr.class);
    List<SDomain> allDomains = bdomainMgr.loadDomainsByParent(role.getDomain().getUuid());

    dd.put("role", role);
    dd.put("shareDomains", shareDomains);
    dd.put("allDomains", allDomains);
    dd.put("domain", domain);
    dd.setWorkingTemplate(TEMPLATE_PUBLIC_SHAREEDIT);
    return ActionConstants.APPLICATIONFRAME;
  }

  public String saveRoleShare() throws Exception {
    SDomain domain = getFormDomain();

    String uuid = (String) dd.getFormValue("role_uuid");
    if (uuid == null)
      throw new Exception("缺少必须的参数role_uuid。");
    String ocaStr = (String) dd.getFormValue("role_oca");
    if (ocaStr == null)
      throw new Exception("缺少必须的参数role_oca。");
    long oca = Long.valueOf(ocaStr).longValue();
    BRole role = getBRoleMgr().loadRole(uuid);
    if (role == null)
      throw new Exception("指定的角色不存在(uuid=" + uuid + ")。");

    List<BRoleShareCommand> cmds = getFormRoleShareCommands();
    if (cmds.size() > 0) {
      IBRoleShareAgent agent = getBRoleMgr().createRoleShareAgent(uuid);
      try {
        agent.executeCommandsT(cmds, new OperateContext(getCurrentUser()), oca);
      } catch (Exception e) {
        e.printStackTrace();
        dd.addErrorText(e.getMessage());
        return showRolePermissionsEditSafely(uuid);
      }
    }

    dd.addHint(CRole.CAPTION_CLASS + "的共享" + CDomain.CAPTION_CLASS + "已保存。");
    dd.put("tabView", "tvShare");
    return showDetailSafely(role, domain, JspLib.VALUE_FORMSTATE_VIEW, false);
  }

  private List<BRoleShareCommand> getFormRoleShareCommands() throws StringTooLongException {
    List<BRoleShareCommand> cmds = new ArrayList<BRoleShareCommand>();
    Iterator keyIterator = dd.createFormPrefixedKeysIterator("ptree_commands_");
    List<String> keys = new ArrayList<String>();
    while (keyIterator.hasNext())
      keys.add((String) keyIterator.next());
    Collections.sort(keys);
    for (int i = 0; i < keys.size(); i++) {
      String key = keys.get(i);
      String value = (String) dd.getFormValue("ptree_commands_" + key);
      String[] items = value.split(";");
      BRoleShareCommand cmd = new BRoleShareCommand();
      cmd.setDomainUuid(items[0]);
      cmd.setCommand(new Integer(items[1]));
      cmds.add(cmd);
    }
    return cmds;
  }
}
